import {
    MeshLambertMaterial,
    Mesh,
    ExtrudeGeometry,
    Shape,
    Vector2

} from 'three';

export default class AreaChart {
    public group: Mesh;
    private smooth: boolean;

    constructor(data: any[] = [], manifest: Manifest) {
        this.group = new Mesh();
        const { smooth } = manifest;
        this.smooth = smooth as boolean;
        data.forEach((item, index) => {
            const pointPosArr = this.getPosArr(item);
            item.forEach((cur: any) => {
                const { color, perWidth } = cur;
                const areaMesh = this.drawArea(color, index, perWidth, pointPosArr);
                this.group.add(areaMesh);
                this.group.position.z = 1;
            })
        });
    }

    private drawArea(color: number, index: number, perWidth: number, pointArr: any[]) {
        const shape = new Shape();
        shape.moveTo(0, 0)
        if (this.smooth) {
            const v2Arr = pointArr.map(item => new Vector2(item[0], item[1]));
            shape.splineThru(v2Arr)
        } else {
            for (const i of pointArr) {
                shape.lineTo(i[0], i[1])
            }
        }
        shape.lineTo(pointArr[pointArr.length - 1][0], 0)
        const extrudeSettings = {
            curveSegments: 4,
            steps: 1,
            depth: 0.06,
            bevelEnabled: false,
            bevelThickness: 0,
            bevelSize: 0,
            bevelOffset: 0,
            bevelSegments: 0
        };
        const geometry = new ExtrudeGeometry(shape, extrudeSettings);
        const material = new MeshLambertMaterial({ color });
        const mesh = new Mesh(geometry, material);
        mesh.position.z -= 0.3 * index;

        return mesh;
    }

    private getPosArr(data: any) {
        const arr = data.reduce((acc: any, cur: any, index: number) => {
            const { perWidth, height } = cur;
            acc.push([perWidth * 2 * index, height]);
            return acc;
        }, [])
        return arr;
    }
}
